package com.siteseat.crudeq.kernel;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import com.siteseat.common.misc.FileHelper;
import com.siteseat.crudeq.common.raw.Constants;

/**
 *
 */
public class ChunkInfo implements Comparable<ChunkInfo>, Constants {

  private QueueProfile     profile;

  private File             file;

  private volatile int     size;

  private Long             chunkId;

  /**
   * @return
   */
  public Integer getQueueId() {
    return getProfile().getId();
  }

  /**
   * Only for create
   * 
   * @param profile
   * @throws FileNotFoundException
   */
  public ChunkInfo( QueueProfile prof, Long chunkId ) throws IOException {    
    String dec = String.format( "%020d", chunkId );// long integer takes 20
    // decimal
    String splitted = dec.substring( 0, 3 ) + File.separator + dec.substring( 3, 6 ) + File.separator
            + dec.substring( 6, 9 ) + File.separator + dec.substring( 9, 12 ) + File.separator + dec.substring( 12, 15 )
            + File.separator + dec.substring( 15, 18 ) + File.separator + dec.substring( 18, 20 );
    String path = prof.getChunkFolderPath() + File.separator + splitted + CHUNK_FILE_DOT_EXTENSION;

    File f = new File( path );
    FileHelper.createFileIfNotExists( f );
    
    construct( prof, chunkId, f );
  }
  
  /**
   * Only for open
   *
   * @param prof
   * @param file
   * @param chunkId
   * @return
   * @throws FileNotFoundException
   */
  public ChunkInfo( QueueProfile prof, File file, Long chunkId ) throws FileNotFoundException {
    construct( prof, chunkId, file );
  }
  
  /**
   * 
   *
   * @param prof
   * @param cid
   * @param f
   * @throws FileNotFoundException 
   */
  private void construct( QueueProfile prof, Long cid, File f ) throws FileNotFoundException {
    this.profile = prof;
    this.chunkId = cid;
    this.file = f;

    this.size = (int)file.length();
  }

  /**
   * Gets the file
   * 
   * @return the file
   */
  public File getFile() {
    return file;
  }

  /**
   * Gets the profile
   * 
   * @return the profile
   */
  public QueueProfile getProfile() {
    return profile;
  }

  /**
   * Gets the chunkId
   * 
   * @return the chunkId
   */
  public Long getChunkId() {
    return chunkId;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public int compareTo( ChunkInfo that ) {
    return (int)( this.chunkId.longValue() - that.chunkId.longValue() );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String toString() {
    return this.file.getAbsolutePath();
  }

  /**
   * @return
   * @throws IOException
   */
  public FileOutputStream create() throws IOException {
    FileHelper.createFileIfNotExists( this.file );

    return new FileOutputStream( this.file, false );
  }

  /**
   * Gets the fileLength
   * 
   * @return the fileLength
   */
  public int getSize() {
    if( this.size == 0 ) {
      this.size = (int)this.file.length();
    }
    return this.size;
  }

  /**
   * @param size
   * @throws IOException 
   */
  public void increaseSize( int delta ) throws IOException {
    assert delta >= 0;
    this.size += delta;
  }

  /**
   * 
   */
  public void clearSize() {
    this.size = 0;
  }

}
